﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace LanguageDetector
{
    [Flags]
    public enum CleanLevel
    {
        None = 0,
        Trim = 1,
        Lower = 2,
        WhiteSpace = 4,
        Marking = 8,
        Digit = 16,
        Alphabet = 32,
        Tag = 64,
    }

    public static partial class ExtensionMethods
    {
        public static bool IsNullOrEmpty<T>(this ICollection<T> self)
        {
            return self == null || self.Count==0;
        }

        public static List<List<T>> ExplodeChunks<T>(this List<T> self, int chunkSize)
        {
            var chunks = new List<List<T>>();
            if (!self.IsNullOrEmpty())
            {
                var maxbatch = (int)Math.Ceiling((double)self.Count / chunkSize);
                for (var i = 0; i < maxbatch; i++)
                {
                    var c = self.Skip(i * chunkSize).Take(chunkSize).ToList();
                    chunks.Add(c);
                }
            }
            return chunks;
        }

        public static readonly Regex RE_WHITESPACE = new Regex(@"\s+", RegexOptions.Compiled);
        public static readonly Regex RE_MARKING = new Regex(@"[`~\!@#\$%\^\&\*\(\)\-_+=\{\}\[\]\\|\:;""'<>,\.\?/]", RegexOptions.Compiled);
        public static readonly Regex RE_DIGIT = new Regex(@"(?:[0-9]+(?:[\.,][0-9]+)*|(?:[\.,][0-9]+)+)", RegexOptions.Compiled);
        public static readonly Regex RE_ALPHABET = new Regex(@"[a-zA-Z]+", RegexOptions.Compiled);
        public static readonly Regex RE_TAG = new Regex(@"</?[a-zA-Z][a-zA-Z0-9]*(?:[^>]{1,200})?/?>", RegexOptions.Compiled);
        public static readonly Regex RE_COMMENT = new Regex(@"<!--.+-->", RegexOptions.Compiled);

        public static string Clean(this string self, CleanLevel level)
        {
            if (!string.IsNullOrEmpty(self))
            {
                if ((level & CleanLevel.Lower) == CleanLevel.Lower)
                    self = self.ToLower();

                if ((level & CleanLevel.Tag) == CleanLevel.Tag)
                {
                    self = RE_COMMENT.Replace(self, " ");
                    self = RE_TAG.Replace(self, " ");
                }

                if ((level & CleanLevel.Digit) == CleanLevel.Digit)
                    self = RE_DIGIT.Replace(self, " ");

                if ((level & CleanLevel.Alphabet) == CleanLevel.Alphabet)
                    self = RE_ALPHABET.Replace(self, " ");

                if ((level & CleanLevel.Marking) == CleanLevel.Marking)
                    self = RE_MARKING.Replace(self, " ");

                if ((level & CleanLevel.WhiteSpace) == CleanLevel.WhiteSpace)
                    self = RE_WHITESPACE.Replace(self, " ");

                if ((level & CleanLevel.Trim) == CleanLevel.Trim) //do this last
                    self = self.Trim();
            }
            return self;
        }
    }
}
